package com.cloud.distribute.lock.generator;

import com.cloud.distribute.lock.annotation.CacheLock;
import com.cloud.distribute.lock.annotation.CacheParam;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * @author zhaoyangfu - 2020/7/22 16:24
 */
public class LockGenerator implements CacheKeyGenerator {

    @Override
    public String getLockKey(ProceedingJoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        CacheLock lock = method.getAnnotation(CacheLock.class);
        final Object[] args = point.getArgs();
        final Parameter[] parameters = method.getParameters();
        StringBuilder sb = new StringBuilder();
        // todo 默认解析方法里面带CacheParam注解的字段,没有则尝试解析实体对象中的
        for (int i = 0; i < args.length; i++) {
            CacheParam annotation = parameters[i].getAnnotation(CacheParam.class);
            if (annotation == null) continue;
            sb.append(lock.delimiter()).append(args[i]);
        }

        if (StringUtils.isEmpty(sb.toString())) {
            for (Object object : args) {
                Field[] fields = object.getClass().getDeclaredFields();
                for (Field field : fields) {
                    CacheParam param = field.getAnnotation(CacheParam.class);
                    if (param == null) continue;
                    field.setAccessible(true);
                    sb.append(lock.delimiter()).append(ReflectionUtils.getField(field, object));
                }
            }
        }
        String key = lock.prefix() + sb.toString();
        System.out.println(String.format("key=>%s", key));
        return key;
    }

}
